#pragma once
#include <iostream>
#include <jsoncpp/json/json.h>

using namespace std;

//定制协议
//定制协议的过程就是完成定制结构化数据的过程
//客户端和服务器要完成通信必定要有请求和响应

//请求协议
typedef struct request
{
    int x;
    int y;
    char op; //"+-*/%"
} request_t;

//相应协议
typedef struct response
{
    int code;   //响应结果的状态码，自己定义(code:0 success code:-1 除0 code:-2 %0 ...)
    int result; //响应的计算结果】
} response_t;

// 上面就是客户端和服务端的通信协议了：客户端发送什么给服务器，而服务器以什么形式返回给客户端，这就是协议
// 假如你是程序员，你编写客户端和服务端时候，业务逻辑处理是要遵守这个约定去处理的；
// 你在编写客户端和服务端时候，是怎么直到业务逻辑怎么处理呢？因为你知道了协议，直到了协议规范约定了客户端和服务端的处理
// 处理的结果以什么形式返回，都是约定决定的
// 发送时候要用序列化和反序列话的形式发送，这样可以保证发送时候的格式是统一的，接收的格式也是统一的
// 假如不使用序列化发送，那么就会可能发送的数据到对方那里，由于操作系统对数据类型的大小解释（也可能软件版本迭代）不一样，
// 导致发送过去的内容对方无法正确的解析成功，所以必须要序列化发送，反序列化接收

// sudo yum install -y jsoncpp-devel 安装jsoncpp
// 安装的位置的头文件在 /usr/include/jsoncpp/json/ 路径下
// 安装的动态库文件在 /usr/lib64/libjson/ 路径下

// request->string
std::string SerializeRequest(const request_t &req)
{
    //序列化的过程

    Json::Value root; // kv键值对，万精油对象什么都可以装
    root["datax"] = req.x;
    root["datay"] = req.y;
    root["operator"] = req.op;

    // Json::StyledWriter writer;
    Json::FastWriter writer;

    //实际在网络传输结构化数据时候，我们发送的是write函数返回的序列化字符串
    std::string json_string = writer.write(root); //返回的是序列化的字符串

     std::cout << json_string << std::endl;
     return json_string;
}
// string->request
void DeserilizeRequest(const std::string &json_string, request_t &out)
{
    //反序列化的过程 
    Json::Reader reader;
    Json::Value root;
    reader.parse(json_string, root);
   
    out.x = root["datax"].asInt();
    out.y = root["datay"].asInt();
    out.op = (char)root["operator"].asInt();
}
std::string SerializeRespsonse(const response_t &resp)
{
    Json::Value root;
    root["code"] = resp.code;
    root["result"] = resp.result;

    Json::FastWriter writer;
    std::string json_string = writer.write(root);

    return json_string;
}
void DeserilizeResponse(const std::string &json_string, response &out)
{
    Json::Reader reader;
    Json::Value root;
    reader.parse(json_string,root);
    out.code = root["code"].asInt();
    out.result = (char)root["result"].asInt();

}   

